package trong.gold.soft.com.view.game;

import trong.gold.soft.com.main.mTetrisMidlet;

import java.io.IOException;
import java.util.Random;
import java.util.Timer;

import trong.gold.soft.com.model.Point;
import trong.gold.soft.com.model.Record;
import trong.gold.soft.com.model.Resources;
import trong.gold.soft.com.model.TestTimer;
import trong.gold.soft.com.model.createImg;
import trong.gold.soft.com.model.font.VietnameseFont;
import trong.gold.soft.com.view.menuSlGame;
import trong.gold.soft.com.view.menuTetris;

import javax.microedition.lcdui.Canvas;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;

public class HotGirl extends Canvas implements Runnable{
	private mTetrisMidlet midlet;
	private static final int DEFAULT_DELAY_TIME = 4;
	private static int DEFAULT_TIMER_DELAY_TIME = 80;
	private static Random random = new Random();
	private static final int TOP_LEFT_ANCHOR = Graphics.TOP | Graphics.LEFT;
	
	private TestTimer testTimer;
	private Timer timer = new Timer();
	private int count = 0;
	
	private int unit = 6;
	private int column = 13;
	private int row = 20;
	private static int vtname;
	private int[][] gameMap = new int[row][column];
	private int state = 0;
	private int rowfull=0;
	private Point currentBlockTopLeftPoint;

	private int[][][] currentBlock;
	private int[][][] nextBlock;
	private int currentColor = 0;
	private int nextColor;
	private LayerManager lm;

	private int[][][][] blockArray = new int[7][][][];
	private String[] brickColorImgName = new String[]{"1.png", "2.png", "3.png", "4.png", "5.png", "6.png"};
	private final String[] giftImgName = new String[]{"1.png","2.png","3.png","4.png"};
	private String[] wingift = new String[]{"1.jpg","2.jpg","3.jpg","4.jpg"};
	private String backgroundImgName = "thong-tin.png";
	private String[] ghostname = new String[] {"ghost.png"};
	private String cap = "Cấp độ";
	private String diem = "Điểm";
	private Image backgroundImage,giftImage,wingiftimg;
	private Image ghostImage;
	private Image[] brickImageColor;
	
	private boolean isGameOver = false;

	private int gameOverDelay = 0;
	private boolean isGameWin = false;
	private boolean kthigh=false;
	private boolean ktfull=false;

	private int countToGoToNextState = 0;
	private int score = 0;
	private int level = 1;
	private int latx=0,laty=0;
	private int delayTime = DEFAULT_DELAY_TIME;
	private boolean isProcessingEndOfBrick = false;

	private int[][] colorMap = new int[][] 
	{
			{ 0, 255, 0 }, // Xanh la cay
			{ 0, 0, 255 }, // Xanh da troi dam
			{ 0, 255, 255 }, // Xanh duong
			{ 255, 0, 255 },  // Tim
			{ 255, 200, 0 }, // Vang nhat
			{ 255, 175, 175 }, // Hong nhat
			{ 255, 255, 0 }  // Vang dam
	};

	private int[][][] leftLBlock = new int[][][] 
    { 
			{
				{ 1, 0, 0 }, 
				{ 1, 1, 1 }, 
				{ 0, 0, 0 } 
			}, 
			{ 
				{ 0, 1, 1 },
				{ 0, 1, 0 }, 
				{ 0, 1, 0 }
			},
			{ 
				{ 0, 0, 0 }, 
				{ 1, 1, 1 }, 
				{ 0, 0, 1 } 
			}, 
			{ 
				{ 0, 1, 0 }, 
				{ 0, 1, 0 }, 
				{ 1, 1, 0 }
			} 
    };

	private int[][][] TBlock = new int[][][] 
    { 
			{ 
				{ 0, 1, 0 }, 
				{ 1, 1, 1 }, 
				{ 0, 0, 0 } 
			}, 
			{ 
				{ 0, 1, 0 }, 
				{ 0, 1, 1 }, 
				{ 0, 1, 0 } 
			},
			{ 
				{ 0, 0, 0 }, 
				{ 1, 1, 1 }, 
				{ 0, 1, 0 } 
			}, 
			{
				{ 0, 1, 0 }, 
				{ 1, 1, 0 }, 
				{ 0, 1, 0 } 
			} 
	};

	private int[][][] leftZBlock = new int[][][] 
    { 
			{ 
				{ 0, 0, 0 }, 
				{ 1, 1, 0 }, 
				{ 0, 1, 1 } 
			}, 
			{ 
				{ 0, 0, 1 }, 
				{ 0, 1, 1 }, 
				{ 0, 1, 0 } 
			} 
	};

	private int[][][] rightZBlock = new int[][][] 
    { 
			{ 
				{ 0, 0, 0 }, 
				{ 0, 1, 1 }, 
				{ 1, 1, 0 } 
			}, 
			{ 
				{ 0, 1, 0 }, 
				{ 0, 1, 1 }, 
				{ 0, 0, 1 } 
			} 
	};

	private int[][][] rightLBlock = new int[][][] 
    { 
			{ 
				{ 0, 0, 0 }, 
				{ 1, 1, 1 }, 
				{ 1, 0, 0 } 
			}, 
			{ 
				{ 1, 1, 0 }, 
				{ 0, 1, 0 }, 
				{ 0, 1, 0 } 
			},
			{ 
				{ 0, 0, 1 }, 
				{ 1, 1, 1 }, 
				{ 0, 0, 0 } 
			}, 
			{ 
				{ 0, 1, 0 }, 
				{ 0, 1, 0 }, 
				{ 0, 1, 1 } 
			} 
	};

	private int[][][] OBlock = new int[][][] 
    { 
			{ 
				{ 1, 1 }, 
				{ 1, 1 } 
			} 
	};

	private int[][][] IBlock = new int[][][] 
    { 
			{ 
				{ 0, 1, 0, 0 }, 
				{ 0, 1, 0, 0 }, 
				{ 0, 1, 0, 0 }, 
				{ 0, 1, 0, 0 } 
			},
			{ 
				{ 0, 0, 0, 0 }, 
				{ 1, 1, 1, 1 }, 
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 } 
			} 
	};

	public HotGirl(mTetrisMidlet midlet){
		testTimer = new TestTimer(this);
		timer.schedule(testTimer, 1, DEFAULT_TIMER_DELAY_TIME);
		setFullScreenMode(true);
		this.midlet = midlet;
		// TODO: x2 all size, must delete this code after release
		unit *= 2;
		blockArray[0] = leftLBlock;
		blockArray[1] = TBlock;
		blockArray[2] = leftZBlock;
		blockArray[3] = rightLBlock;
		blockArray[4] = OBlock;
		blockArray[5] = rightZBlock;
		blockArray[6] = IBlock;
		
		brickImageColor = new Image[brickColorImgName.length];
		for (int i = 0; i < brickImageColor.length; i++) {
			try {
				brickImageColor[i] = Image.createImage("/com/image/imggame/brick/" + brickColorImgName[i]);
				brickImageColor[i] = Image.createImage(brickImageColor[i], 0, 0, unit, unit, Sprite.TRANS_NONE);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			int giftImgNameIndex = level - 1;
			if (giftImgNameIndex > giftImgName.length - 1) {
				giftImgNameIndex = giftImgName.length - 1;
			}
			giftImage = Image.createImage("/com/image/imggame/gift/" + giftImgName[giftImgNameIndex]);
			wingiftimg = Image.createImage("/com/image/imggame/gift/" + wingift[giftImgNameIndex]);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
			backgroundImage = createImg.createImage("/com/image/" + backgroundImgName);
			
		try {
			ghostImage = Image.createImage("/com/image/imggame/brick/" + ghostname[0]);
			ghostImage = Image.createImage(ghostImage, 0, 0, unit, unit, Sprite.TRANS_NONE);
		} catch (IOException e) {
			e.printStackTrace();
		}
		createBlock();

	}

	protected void paint(Graphics g) {
	//	randomColor();
		if(isGameOver){
			g.setColor(0xb8f1e2);
			g.fillRect(20, this.getHeight()/3, this.getWidth() - 40, Resources.imgkthuc.getHeight());
			g.drawImage(Resources.imgkthuc, this.getWidth()/2 - Resources.imgkthuc.getWidth()/2, this.getHeight()/3, Resources.TOP_LEFT_ANCHOR);
			VietnameseFont.BlackBold.DrawString(g, "Ấn phím bất kỳ",this.getWidth()/2, this.getHeight() - VietnameseFont.WhiteBold.getHeight(), Graphics.HCENTER);
			return;
		}

		
		drawNextStep(g);
		
		if(isGameWin){
			countToGoToNextState++;
			g.drawImage(wingiftimg, 0, 0,  Resources.TOP_LEFT_ANCHOR);
			g.drawImage(Resources.imglevel, this.getWidth()/2 - Resources.imglevel.getWidth()/2, this.getHeight()/3, Resources.TOP_LEFT_ANCHOR);
			VietnameseFont.BlackBold.DrawString(g, "Ấn phím bất kỳ",this.getWidth()/2, this.getHeight() - VietnameseFont.WhiteBold.getHeight(), Graphics.HCENTER);
			return;
		}
		
		if (isProcessingEndOfBrick) {
			return;
		}
		fallByStep();
	}
	
	private void drawNextStep(Graphics g) {
		clearAll(g);
		drawBackGround(g);
		drawScore(g);
		drawNextBlock(g);
		updateMap();
		drawMap(g);
		drawhotgirl(g);
		getghosty(g);
		if(rowfull>=2)
			drawanhanh(g);

		
	}
	private void drawanhanh(Graphics g){
		lm.paint(g, this.getWidth() - Resources.imgtrthai.getWidth()/2 - Resources.mesgirl.getWidth(), 60 + VietnameseFont.Black.getHeight()*4);
		VietnameseFont.BlackBold.DrawString(g, "Rất tuyệt",this.getWidth() - Resources.imgtrthai.getWidth()/2 - Resources.mesgirl.getWidth()/2,  60 + VietnameseFont.Black.getHeight()*4 + 5, Graphics.HCENTER);

		rowfull=0;
	}
	private int indexcurr=0;;
	private void drawhotgirl(Graphics g){
		 int x=50;
		 int y=5;
		 int gardenCols, gardenRows;
		 int[] bgIndexes;

		 gardenCols= getWidth()/x;
	     gardenRows=getHeight()/y;
	     bgIndexes=new int[]{
	        		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
	        };

	     LayerManager lm1 = new LayerManager();
			TiledLayer background =new TiledLayer(gardenCols, gardenRows,giftImage,x, y);
			if(indexcurr>0){
				 for(int i=0;i<indexcurr;i++){
			    	background.setCell(0, i, bgIndexes[i]);
			    	
			    }
			    lm1.append(background);
			    lm1.paint(g, backgroundImage.getWidth() + 5, 60 + VietnameseFont.Black.getHeight()*5);

			}
	}
	private void createBlock() {
		state = 0;
		if (nextBlock != null) {
			currentBlock = nextBlock;
			currentColor = nextColor;
		} else {
			currentBlock = blockArray[random.nextInt(blockArray.length)];
			currentColor = getDifferentRandomColor(currentColor, brickImageColor.length);
		}
		nextBlock = blockArray[random.nextInt(blockArray.length)];
		nextColor = getDifferentRandomColor(currentColor, brickImageColor.length);
		currentBlockTopLeftPoint = new Point(column / 2 - 1, -2);
	}
	private int getDifferentRandomColor(int differentWithValue, int maxValue) {
		int randomValue = 0;
		do {
			randomValue = random.nextInt(maxValue) + 2;
		} while (randomValue == differentWithValue);
		return randomValue;
	}
	
	private void drawScore(Graphics g) {
		VietnameseFont.Black.DrawString(g,cap, 186 + VietnameseFont.Black.getWidth(cap)/2, 60, Graphics.HCENTER);
		VietnameseFont.Black.DrawString(g,"" + level, 186 + VietnameseFont.Black.getWidth(cap)/2, 60 + VietnameseFont.Black.getHeight(), Graphics.HCENTER);
		VietnameseFont.Black.DrawString(g,diem, 186 + VietnameseFont.Black.getWidth(cap)/2, 60 + VietnameseFont.Black.getHeight()*2, Graphics.HCENTER);
		VietnameseFont.Black.DrawString(g,"" + score, 186 + VietnameseFont.Black.getWidth(cap)/2, 60 + VietnameseFont.Black.getHeight()*3, Graphics.HCENTER);
		VietnameseFont.Black.DrawString(g,"Girl", 186 + VietnameseFont.Black.getWidth(cap)/2, 60 + VietnameseFont.Black.getHeight()*4, Graphics.HCENTER);
		
	}
	private void drawNextBlock(Graphics g) {
		if (nextBlock != null) {
			for (int i = 0; i < nextBlock[0].length; i++) {
				for (int j = 0; j < nextBlock[0][i].length; j++) {
					if (nextBlock[0][i][j] == 1) {
						g.drawImage(brickImageColor[nextColor - 2], (column + j) * unit + 36, (i + 1) * unit, TOP_LEFT_ANCHOR);
					}
				}
			}
		}
	}

	private void clearAll(Graphics g) {
		
		for(int i=0;i<=this.getWidth()/44;i++){
			g.drawImage(Resources.backgr, i*Resources.backgr.getWidth(), 0, Resources.TOP_LEFT_ANCHOR);
		}
		g.drawImage(Resources.imgicon, this.getWidth()/2 - Resources.imgicon.getWidth()/2, 10, Resources.TOP_LEFT_ANCHOR);
	}

	private void drawBackGround(Graphics g) {
		g.drawImage(backgroundImage, 0, 0, TOP_LEFT_ANCHOR);
		g.drawImage(Resources.imgtrthai, backgroundImage.getWidth(), 0, Resources.TOP_LEFT_ANCHOR);
		if(hasPointerEvents()){
			g.drawImage(Resources.leftImg, this.getWidth()/2 - Resources.leftImg.getWidth()*2 - 20, this.getHeight() - Resources.leftImg.getHeight() - 5, Resources.TOP_LEFT_ANCHOR);
			g.drawImage(Resources.downImg, this.getWidth()/2 - Resources.leftImg.getWidth() - 10, this.getHeight() - Resources.leftImg.getHeight() - 5, Resources.TOP_LEFT_ANCHOR);
			g.drawImage(Resources.xoayImg, this.getWidth()/2 + Resources.leftImg.getWidth()*2 + 10, this.getHeight() - Resources.leftImg.getHeight() - 5, Resources.TOP_LEFT_ANCHOR);
			g.drawImage(Resources.rightImg, this.getWidth()/2 + Resources.leftImg.getWidth()*2 + 20, this.getHeight() - Resources.leftImg.getHeight() - 5, Resources.TOP_LEFT_ANCHOR);
		}
		
	}
	
	private void clearCurrentBlock() {
		for (int i = 0; i < currentBlock[state].length; i++) {
			for (int j = 0; j < currentBlock[state][i].length; j++) {
				if ((currentBlockTopLeftPoint.x + i > -1) && (currentBlockTopLeftPoint.y + j > -1)) {
					if ((currentBlockTopLeftPoint.y + j < gameMap.length) && (currentBlockTopLeftPoint.x + i < gameMap[currentBlockTopLeftPoint.y + j].length)) {
						if (currentBlock[state][j][i] > 0) {
							gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] = 0;
							
						}
					}
				}
			}
		}
	}
	private void drawMap(Graphics g) {
		for (int i = 0; i < gameMap.length; i++) {
			for (int j = 0; j < gameMap[i].length; j++) {
				if (gameMap[i][j] == 1) {
					if (brickImageColor[currentColor - 2] != null) {
						g.drawImage(brickImageColor[currentColor-2], j * unit + unit, i * unit, TOP_LEFT_ANCHOR);
						
					}
				} else if (gameMap[i][j] > 1) {
					if (brickImageColor[currentColor - 2] != null) {
						g.drawImage(brickImageColor[gameMap[i][j] - 2], j * unit + unit, i * unit, TOP_LEFT_ANCHOR);
					}
				}
			}
		}

		//drawghostBlock(g);
//		for (int i = 0; i < gameMap.length; i++) {
//			for (int j = 0; j < gameMap[i].length; j++) {
//				if (gameMap[i][j] == 1) {
//					g.drawImage(ghostImage,(j) * unit, i  * unit, TOP_LEFT_ANCHOR);
//				}
//			}
//		}
	}
	private void getghosty(Graphics g){
		if (currentBlock != null) {
			for (int i = 0; i < currentBlock[state].length; i++) {
				for (int j = 0; j < currentBlock[state][i].length; j++) {
					if (currentBlock[state][i][j] == 1) {
					//	g.drawImage(brickImageColor[nextColor - 2], (column + 2 + j) * unit, (i + 6) * unit, TOP_LEFT_ANCHOR);
						g.drawImage(ghostImage,(currentBlockTopLeftPoint.x+j) * unit + unit, (getBottomPoint(false) + i) * unit, TOP_LEFT_ANCHOR);
					}
				}
			}
//					g.drawImage(ghostImage,currentBlockTopLeftPoint.x * unit, 10 * unit, TOP_LEFT_ANCHOR);
		}
	}
	private void updateMap() {
		if (isProcessingEndOfBrick) {
			return;
		}
		
		for (int i = 0; i < currentBlock[state].length; i++) {
			for (int j = 0; j < currentBlock[state][i].length; j++) {
				if ((currentBlockTopLeftPoint.x + i > -1) && (currentBlockTopLeftPoint.y + j > -1)) {
					if ((currentBlockTopLeftPoint.y + j < gameMap.length) && (currentBlockTopLeftPoint.x + i < gameMap[currentBlockTopLeftPoint.y + j].length)) {
						if ((currentBlock[state][j][i] > 0) && (gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] == 0)) {
							gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] = 1;
						}
					}
				}
			}
		}
	}

	private boolean checkGameOverCondition() {
		for (int i = 0; i < gameMap.length; i++) {
			if (isRowEmpty(i)) {
				return false;
			}
		}
		return true;
	}
	private void goToNextLevel() {
		level++;
		delayTime = DEFAULT_DELAY_TIME - level / 2;
		if (delayTime < 0) {
			delayTime = 0;
		}
		try {
			int giftImgNameIndex = level - 1;
			if (giftImgNameIndex > giftImgName.length - 1) {
				giftImgNameIndex = giftImgName.length - 1;
			}
			giftImage = Image.createImage("/com/image/imggame/gift/" + giftImgName[giftImgNameIndex]);
			wingiftimg = Image.createImage("/com/image/imggame/gift/" + wingift[giftImgNameIndex]);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Reset gameMap
		for (int i = 0; i < gameMap.length; i++) {
			for (int j = 0; j < gameMap[i].length; j++) {
				gameMap[i][j] = 0;
			}
		}
//		nextBlock = null;
		createBlock();
		indexcurr=0;
	}
	
	private void processEndOfBrick() {
		new Thread() {
			public void run() {
				isProcessingEndOfBrick = true;
				if (checkGameOverCondition()) {
					gameOverDelay++;
					if (gameOverDelay > 1) {
						isGameOver = true;
						isProcessingEndOfBrick = false;
						return;
					}
				}
				
				updateMapWithColor();
				int beginRow = currentBlockTopLeftPoint.y + currentBlock[state].length - 1;
				if (beginRow > gameMap.length - 1) {
					beginRow = gameMap.length - 1;
				}

				int[] fullRow = new int[0];
				
				
				do {
					fullRow = checkFullRow(beginRow);
					
					if (fullRow.length != 0) {
						deleteLine(fullRow[0]);
						try {
							sleep(200);
						} catch (InterruptedException e) {
						}
						fallAfterDeleteLine(beginRow, fullRow);
					}
				} while (fullRow.length != 0); 
				
				if (checkGameWin()) {
					isProcessingEndOfBrick = false;
					return;
				}
				ktfull=false;
				
				createBlock();
				isProcessingEndOfBrick = false;
			}
		}.start();
	}

	private void updateMapWithColor() {
		for (int i = 0; i < currentBlock[state].length; i++) {
			for (int j = 0; j < currentBlock[state][i].length; j++) {
				if ((currentBlockTopLeftPoint.x + i > -1) && (currentBlockTopLeftPoint.y + j > -1)) {
					if ((currentBlockTopLeftPoint.y + j < gameMap.length) && (currentBlockTopLeftPoint.x + i < gameMap[currentBlockTopLeftPoint.y + j].length)) {
						if (currentBlock[state][j][i] > 0) {
							gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] = currentColor;
						}
					}
				}
			}
		}
	}

	private int[] checkFullRow(int beginRow) {
		int[] fullRow = new int[4];
		int fullRowIndex = 0;
		int currentRow = beginRow;
		while (!isRowEmpty(currentRow) && (currentRow > 0)) {
			if (isRowFull(currentRow)) {
				fullRow[fullRowIndex] = currentRow;
				fullRowIndex++;
			}
			currentRow--;
		}

		if (fullRowIndex == 0) {
			return new int[0];
		} else {
			int[] returnArray = new int[fullRowIndex];
			System.arraycopy(fullRow, 0, returnArray, 0, returnArray.length);
			if(!ktfull){
				rowfull=returnArray.length;
				System.out.println("vua an so hang la: " + rowfull);
				ktfull=true;
			}
			
			return returnArray;
		}
		
	}
	
	private void drawtripbo(){
			int kt=rowfull;
				lm = new LayerManager();
				TiledLayer an = null;
				an =new TiledLayer(1, 1,Resources.mesgirl,120, 62);
				if(kt>=2){
					
					an.setCell(0, 0, 1);
					lm.append(an);
				}else{
					an.setCell(0, 0, 0);
					lm.append(an);
				}
				
	}
	private void deleteLine(int row) {
		increateScore();
		for (int i = 0; i < gameMap[row].length; i++) {
			gameMap[row][i] = 0;
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
			}
		}
	}
	//tinh diem
	private void increateScore() {
		score++;
		if(rowfull==2)
			score+=1;
		if(rowfull==3)
			score+=2;
		if(rowfull==4)
			score+=3;;
		if (indexcurr<16) {
			indexcurr+=1;
		}
		drawtripbo();
	}
	//check win
	private boolean checkGameWin() {
		
		if (score>=level * 17) {
			isGameWin = true;
			if(DEFAULT_TIMER_DELAY_TIME >5)
				DEFAULT_TIMER_DELAY_TIME -= 5;
			timer.cancel();
			timer = new Timer();
			testTimer=null;
			testTimer = new TestTimer(this);
			timer.schedule(testTimer, 1, DEFAULT_TIMER_DELAY_TIME);
		}
		return isGameWin;
	}

	private void fallAfterDeleteLine(int beginRow, int[] deletedRow) {
		int currentRow = beginRow;
		int processedDeleteRowCount = 0;
		while ((processedDeleteRowCount < deletedRow.length) && (currentRow > 0)) {
			if (isRowEmpty(currentRow)) {
				shiftRowDown(currentRow);
				intcreate(deletedRow);
				processedDeleteRowCount++;
			} else {
				currentRow--;
			}
		}
	}

	private void shiftRowDown(int beginRow) {
		for (int i = beginRow; i > 0; i--) {
			for (int j = 0; j < gameMap[i].length; j++) {
				gameMap[i][j] = gameMap[i - 1][j];
			}
		}
		for (int j = 0; j < gameMap[0].length; j++) {
			gameMap[0][j] = 0;
		}
	}

	private void intcreate(int[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i]++;
		}
	}

//	private boolean contains(int[] array, int number) {
//		for (int i = 0; i < array.length; i++) {
//			if (array[i] == number) {
//				return true;
//			}
//		}
//		return false;
//	}

	private boolean isRowFull(int checkRow) {
		for (int i = 0; i < gameMap[checkRow].length; i++) {
			if (gameMap[checkRow][i] == 0) {
				return false;
			}
		}
		return true;
	}

	private boolean isRowEmpty(int row) {
		for (int i = 0; i < gameMap[row].length; i++) {
			if (gameMap[row][i] > 0) {
				return false;
			}
		}
		return true;
	}
	
	private void luukthuc(){
		Record.open();
		Record.load();
		for(int i=0;i<Resources.score.length;i++){
			if(score>=Resources.score[i]){
				kthigh=true;
				vtname=i;
				for(int j= Resources.score.length - 1;j >=i+1;j--){
					Resources.score[j]= Resources.score[j-1];
				}
				Resources.score[i]=score;
				break;
			}
		}
		Record.close();
		
	}
	protected void keyRepeated(int keyCode) {
		if (isGameWin) {
			return;
		}
		keyReleased(keyCode);
	}

	protected void keyReleased(int keyCode) {
		if(isGameOver){
			luukthuc();
			setnull();
			Runtime.getRuntime().gc();
			if(kthigh)
				midlet.switchState(this,new viewUser(midlet));
			else
				midlet.switchState(this,new menuSlGame(midlet));
			return;
		}
		
		if (isGameWin && countToGoToNextState > 10) {
			countToGoToNextState = 0;
			isGameWin = false;
			goToNextLevel();
			return;
		}
		
		synchronized (currentBlockTopLeftPoint) {
			clearCurrentBlock();
			updateMap();
			switch (keyCode) {
			case -3:
				if (currentBlockTopLeftPoint.x < 1) {
					for (int i = 0; i < currentBlock[state].length; i++) {
						int column = -currentBlockTopLeftPoint.x;
						if (currentBlock[state][i][column] == 1) {
							return;
						}
					}
				}

				for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
					for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
						if ((i > -1) && (j - 1 > -1) && (i < gameMap.length) && (j < gameMap[i].length)) {
							if ((currentBlock[state][i - currentBlockTopLeftPoint.y][j - currentBlockTopLeftPoint.x] == 1) && (gameMap[i][j - 1] > 1)) {
								return;
							}
						}
					}
				}
				clearCurrentBlock();
				currentBlockTopLeftPoint.x--;
				break;
			case -4:
				if (currentBlockTopLeftPoint.x > gameMap[0].length - currentBlock[state].length - 1) {
					for (int i = 0; i < currentBlock[state].length; i++) {
						int column = gameMap[0].length - currentBlockTopLeftPoint.x - 1;
						if (currentBlock[state][i][column] == 1) {
							return;
						}
					}
				}

				for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
					for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
						if ((i > -1) && (j > -1) && (i < gameMap.length) && (j + 1 < gameMap[i].length)) {
							if ((currentBlock[state][i - currentBlockTopLeftPoint.y][j - currentBlockTopLeftPoint.x] == 1) && (gameMap[i][j + 1] > 1)) {
								return;
							}
						}
					}
				}

				clearCurrentBlock();
				currentBlockTopLeftPoint.x++;
				break;
			case -2:
				if (currentBlockTopLeftPoint.y > gameMap.length - currentBlock[state].length - 1) {
					for (int i = 0; i < currentBlock[state][currentBlock[state].length - 1].length; i++) {
						int column = gameMap.length - currentBlockTopLeftPoint.y - 1;
						if (currentBlock[state][column][i] == 1) {
							processEndOfBrick();
							return;
						}
					}
				}

				for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
					for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
						if ((i > -1) && (j > -1) && (i + 1 < gameMap.length) && (j < gameMap[i + 1].length)) {
							if ((gameMap[i][j] == 1) && (gameMap[i + 1][j] > 1)) {
								processEndOfBrick();
								return;
							}
						}
					}
				}
				clearCurrentBlock();
				currentBlockTopLeftPoint.y++;
				
				// Fall more time
				count = delayTime;
				break;
			case -1:
				int nextState = (state + 1) % currentBlock.length;
				if (currentBlockTopLeftPoint.x < 0) {
					for (int i = 0; i < currentBlock[nextState].length; i++) {
						int column = -currentBlockTopLeftPoint.x - 1;
						if (currentBlock[nextState][i][column] == 1) {
							return;
						}
					}
				}
				if (currentBlockTopLeftPoint.x > gameMap[0].length - currentBlock[nextState].length) {
					for (int i = 0; i < currentBlock[nextState].length; i++) {
						int column = gameMap[0].length - currentBlockTopLeftPoint.x;
						if (currentBlock[nextState][i][column] == 1) {
							return;
						}
					}
				}

				for (int i = 0; i < currentBlock[nextState].length; i++) {
					for (int j = 0; j < currentBlock[nextState].length; j++) {
						if ((currentBlockTopLeftPoint.x + i > -1) && (currentBlockTopLeftPoint.y + j > -1)) {
							if ((currentBlockTopLeftPoint.y + j < gameMap.length) && (currentBlockTopLeftPoint.x + i < gameMap[currentBlockTopLeftPoint.y + j].length)) {
								if (currentBlock[nextState][j][i] > 0 && (gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] > 1)) {
									return;
								}
							}
						}
					}
				}
				clearCurrentBlock();
				state = nextState;
				break;
			case -5:
				clearCurrentBlock();
				currentBlockTopLeftPoint.y = getBottomPoint(true);
				processEndOfBrick();
				break;
			case -7:
				setnull();
				Runtime.getRuntime().gc();
				midlet.switchState(this,new menuTetris(midlet));
				break;
			}
		}
	}
	private void setnull() {
		
//		random=null;
		testTimer=null;
		timer=null;
		currentBlockTopLeftPoint=null;
		brickColorImgName=null;
		backgroundImgName=null;
		ghostname=null;
		ghostImage=null;
		brickImageColor=null;
		IBlock=null;
		colorMap=null;
		leftLBlock=null;
		leftZBlock=null;
		rightLBlock=null;
		OBlock=null;
		rightZBlock=null;
		TBlock=null;
		backgroundImage=null;
		gameMap=null;
		currentBlock=null;
		nextBlock=null;
		blockArray=null;
		cap=null;
		diem=null;
		giftImage=null;
		lm=null;
		wingift=null;
	}
	private void init(int x){
		switch(x){
		case -1:
			int nextState = (state + 1) % currentBlock.length;
			if (currentBlockTopLeftPoint.x < 0) {
				for (int i = 0; i < currentBlock[nextState].length; i++) {
					int column = -currentBlockTopLeftPoint.x - 1;
					if (currentBlock[nextState][i][column] == 1) {
						return;
					}
				}
			}
			if (currentBlockTopLeftPoint.x > gameMap[0].length - currentBlock[nextState].length) {
				for (int i = 0; i < currentBlock[nextState].length; i++) {
					int column = gameMap[0].length - currentBlockTopLeftPoint.x;
					if (currentBlock[nextState][i][column] == 1) {
						return;
					}
				}
			}

			for (int i = 0; i < currentBlock[nextState].length; i++) {
				for (int j = 0; j < currentBlock[nextState].length; j++) {
					if ((currentBlockTopLeftPoint.x + i > -1) && (currentBlockTopLeftPoint.y + j > -1)) {
						if ((currentBlockTopLeftPoint.y + j < gameMap.length) && (currentBlockTopLeftPoint.x + i < gameMap[currentBlockTopLeftPoint.y + j].length)) {
							if (currentBlock[nextState][j][i] > 0 && (gameMap[currentBlockTopLeftPoint.y + j][currentBlockTopLeftPoint.x + i] > 1)) {
								return;
							}
						}
					}
				}
			}
			clearCurrentBlock();
			state = nextState;
			break;
		case -2:
			if (currentBlockTopLeftPoint.y > gameMap.length - currentBlock[state].length - 1) {
				for (int i = 0; i < currentBlock[state][currentBlock[state].length - 1].length; i++) {
					int column = gameMap.length - currentBlockTopLeftPoint.y - 1;
					if (currentBlock[state][column][i] == 1) {
						processEndOfBrick();
						return;
					}
				}
			}

			for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
				for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
					if ((i > -1) && (j > -1) && (i + 1 < gameMap.length) && (j < gameMap[i + 1].length)) {
						if ((gameMap[i][j] == 1) && (gameMap[i + 1][j] > 1)) {
							processEndOfBrick();
							return;
						}
					}
				}
			}
			clearCurrentBlock();
			currentBlockTopLeftPoint.y++;
			
			// Fall more time
			count = delayTime;
			break;
		case -3:
			if (currentBlockTopLeftPoint.x < 1) {
				for (int i = 0; i < currentBlock[state].length; i++) {
					int column = -currentBlockTopLeftPoint.x;
					if (currentBlock[state][i][column] == 1) {
						return;
					}
				}
			}

			for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
				for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
					if ((i > -1) && (j - 1 > -1) && (i < gameMap.length) && (j < gameMap[i].length)) {
						if ((currentBlock[state][i - currentBlockTopLeftPoint.y][j - currentBlockTopLeftPoint.x] == 1) && (gameMap[i][j - 1] > 1)) {
							return;
						}
					}
				}
			}
			clearCurrentBlock();
			currentBlockTopLeftPoint.x--;
			break;
		case -4:
			if (currentBlockTopLeftPoint.x > gameMap[0].length - currentBlock[state].length - 1) {
				for (int i = 0; i < currentBlock[state].length; i++) {
					int column = gameMap[0].length - currentBlockTopLeftPoint.x - 1;
					if (currentBlock[state][i][column] == 1) {
						return;
					}
				}
			}

			for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
				for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
					if ((i > -1) && (j > -1) && (i < gameMap.length) && (j + 1 < gameMap[i].length)) {
						if ((currentBlock[state][i - currentBlockTopLeftPoint.y][j - currentBlockTopLeftPoint.x] == 1) && (gameMap[i][j + 1] > 1)) {
							return;
						}
					}
				}
			}

			clearCurrentBlock();
			currentBlockTopLeftPoint.x++;
			break;
		case -5:
			clearCurrentBlock();
			currentBlockTopLeftPoint.y = getBottomPoint(true);
			processEndOfBrick();
			break;
		case -7:
			setnull();
			Runtime.getRuntime().gc();
			midlet.switchState(this,new menuTetris(midlet));
			break;
		}
	}
	protected void pointerReleased(int x,int y){
		latx=x;
		laty=y;
		for(int i=this.getWidth()/2 - Resources.leftImg.getWidth()*2 - 20;i<this.getWidth()/2 - Resources.leftImg.getWidth() - 20;i++){
			for(int j=this.getHeight() - Resources.leftImg.getHeight() - 5;j<=this.getHeight() - 5;j++){
				if(i==latx && j==laty){
					init(-3);
					return;
				}
			
			}
		}
			
		for(int i=this.getWidth()/2 - Resources.leftImg.getWidth() - 10;i<=this.getWidth()/2 -10;i++)
			for(int j=this.getHeight() - Resources.leftImg.getHeight() - 5;j<=this.getHeight() - 5;j++){
				if(i==latx && j==laty){
					init(-2);
					return;
				}
			}
		for(int i=this.getWidth()/2 + 10;i<=this.getWidth()/2 + Resources.leftImg.getWidth() +10;i++)
			for(int j=this.getHeight() - Resources.leftImg.getHeight() - 5;j<=this.getHeight() - 5;j++){

				if(i==latx && j==laty){
					init(-1);
					return;
				}
			}
		for(int i=this.getWidth()/2 + Resources.leftImg.getWidth() + 20;i<=this.getWidth()/2 + 2*Resources.leftImg.getWidth() + 20;i++)
			for(int j=this.getHeight() - Resources.leftImg.getHeight() - 5;j<=this.getHeight() - 5;j++){	
				if(i==latx && j==laty){
					init(-4);
					return;
				}
			}
		for(int i=0;i<this.getWidth();i++)
			for(int j=0;j<=this.getHeight() - 50;j++){
				init(-5);
				return;
			}
	}
	private int getBottomPoint(boolean a){
		int[] startArray = new int[currentBlock[state][0].length];
		for (int i = 0; i < currentBlock[state].length; i++) {
			for (int j = 0; j < startArray.length; j++) {
				if (currentBlock[state][i][j] == 1) {
					startArray[j] = i;
				}
			}
		}
		int maxPoint = getMaxValue(startArray);
		int rowAfterFall = gameMap.length - 1 - maxPoint;
		for (int i = 0; i < gameMap.length - currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
			for (int j = 0; j < startArray.length; j++) {
				if ((startArray[j] != 0) && (startArray[j] + i + currentBlockTopLeftPoint.y < gameMap.length) && (currentBlockTopLeftPoint.x + j < gameMap[0].length)) {
					if ((startArray[j] + i + currentBlockTopLeftPoint.y) > 0 && (currentBlockTopLeftPoint.x + j) > -1) {
						if(a){
							if (gameMap[startArray[j] + i + currentBlockTopLeftPoint.y][currentBlockTopLeftPoint.x + j] > 0) {
								rowAfterFall = i + currentBlockTopLeftPoint.y - 1;
								return rowAfterFall;
							}
						}else{
							if (gameMap[startArray[j] + i + currentBlockTopLeftPoint.y][currentBlockTopLeftPoint.x + j] > 1) {
								rowAfterFall = i + currentBlockTopLeftPoint.y - 1;
								return rowAfterFall;
							}
						}
						
					}
				}
			}
		}
		return rowAfterFall;
	}
	
	private int getMaxValue(int[] array) {
		int max = array[0];
		for (int i = 1; i < array.length; i++) {
			if (array[i] > max) {
				max = array[i];
			}
		}
		return max;
	}
	
	private void fallByStep() {
		synchronized (currentBlockTopLeftPoint) {
			count++;
			if (count > delayTime) {
				if (currentBlockTopLeftPoint.y > gameMap.length - currentBlock[state].length - 1) {
					for (int i = 0; i < currentBlock[state][currentBlock[state].length - 1].length; i++) {
						int column = gameMap.length - currentBlockTopLeftPoint.y - 1;
						if (currentBlock[state][column][i] == 1) {
							processEndOfBrick();
							return;
						}
					}
				}
				for (int i = currentBlockTopLeftPoint.y; i < currentBlockTopLeftPoint.y + currentBlock[state].length; i++) {
					for (int j = currentBlockTopLeftPoint.x; j < currentBlockTopLeftPoint.x + currentBlock[state].length; j++) {
						if ((i > -1) && (j > -1) && (i + 1 < gameMap.length) && (j < gameMap[i + 1].length)) {
							if ((gameMap[i][j] == 1) && (gameMap[i + 1][j] > 1)) {
								processEndOfBrick();
								return;
							}
						}
					}
				}
				clearCurrentBlock();
				currentBlockTopLeftPoint.y++;
				count = 0;
			}
		}
	}
	public static int getvtname(){
		return vtname;
	}
	public void run() {
		// TODO Auto-generated method stub
		
	}
}